<!--
 * @Date: 2024-07-30 10:42:03
 * @Author: LiSong
 * @LastEditors: LiSong
 * @LastEditTime: 2024-10-30 14:07:59
 * @Description: 表格超链接属性配置
-->
<template>
  <vxe-modal v-bind="dialogOptions" v-model="dialogVisible" @close="modalClose">
    <div class="">
      <el-alert style="margin-bottom: 15px;" title="信息提示" type="info" :closable="false">
        <p>1、新增参数项不录入默认值时，默认取当前列表中的对应字段数据。</p>
        <p>2、链接中可使用#{field}，作为占位符取值！示例：id=#{id}</p>
      </el-alert>
      <el-form size='default'>
        <el-form-item label="链接信息">
          <el-input disabled v-model="mergeLink" />
        </el-form-item>
        <el-form-item label="链接地址">
          <el-input
            v-model="linkInfo.linkUrl"
            placeholder='请输入链接地址'
          />
        </el-form-item>
        <el-form-item label="参数信息">
          <div v-if="linkInfo.paramList.length" class="params-info-wrapper">
            <ul class="info-row">
              <li class="info-row-item info-row-item-label">字段关键词</li>
              <li class="info-row-item info-row-item-label">取值关键词</li>
              <li class="info-row-item info-row-item-label">默认值</li>
              <li class="info-row-item-btn info-row-item-label">操作</li>
            </ul>
            <ul class="info-row" v-for="(paramItem, index) in linkInfo.paramList">
              <li class="info-row-item">
                <el-autocomplete
                  v-model="paramItem.key"
                  style="width: 100%;"
                  clearable
                  placeholder="请输入字段关键词"
                  :trigger-on-focus="false"
                  :fetch-suggestions="paramKeyFilter"
                />
              </li>
              <li class="info-row-item">
                <el-autocomplete
                  v-model="paramItem.code"
                  style="width: 100%;"
                  clearable
                  placeholder="请输入取值关键词"
                  :trigger-on-focus="false"
                  :fetch-suggestions="paramKeyFilter"
                />
              </li>
              <li class="info-row-item">
                <el-input
                  v-model="paramItem.value"
                  placeholder='请输入默认值'
                />
              </li>
              <li class="info-row-item-btn">
                <el-button size="small" type="primary" :icon="Plus" circle @click="addParamItem(index)"/>
                <el-button size="small" type="danger" :icon="Minus" circle @click="delParamItem(index)"/>
              </li>
            </ul>
          </div>
          <el-button v-else link type="primary"  @click="addParamItem(0)">
            新增参数项
          </el-button>
        </el-form-item>
      </el-form>
    </div>
    <template #footer>
      <el-button size="default" type="primary" @click="handleConfirm">保存</el-button>
      <el-button size="default" type="primary" @click="handleClose">取消</el-button>
    </template>
  </vxe-modal>
</template>

<script setup name="ParamsDialog">
import XEUtils from 'xe-utils';

import { reactive, ref, computed } from 'vue';
import { Plus, Minus } from '@element-plus/icons-vue'

import { baseAttrs } from '@/components/dialogs/cfg/base-cofig.js'

const emits = defineEmits(['close', 'confirm']);

const props = defineProps({
  fieldOptions: { type: Array, default: [] }
})

const dialogOptions = reactive({
  ...baseAttrs,
  title: '超链接信息',
  width: '45%',
  height: 450,
  showZoom: false,
  position: { top: 150 },
  className: `${baseAttrs.className} field-lind-dialog`,
  showClose: true,
});

const dialogVisible = ref(false);
const modalClose = () => {
  linkInfo.linkUrl = ''
  linkInfo.paramList = []
  dialogVisible.value = false
}
const handleOpen = ({ row, column }) => {
  // 显示弹窗
  dialogVisible.value = true
  // 设置超链接信息
  setLinkInfo(row[column.field])
}
const handleClose = () => {
  modalClose()
}
const handleConfirm = () => {
  // 获取最终的地址
  const finalLinkUrl = getFinalLinkUrl()
  // 设置值
  emits('confirm', XEUtils.clone(finalLinkUrl, true))
  modalClose()
}
// ----- 表单操作
const linkInfo = reactive({
  linkUrl: '',
  paramList: []
})
const mergeLink = computed(() => {
  return getFinalLinkUrl()
})
/**
 * 设置参数列表数据
 *
 * @param {String} content 目标内容
 */
const setLinkInfo = (content) => {
  if (!content) return;
  // 标识
  let mask = '?'
  let maskIndex = 0
  let frontLink = ''
  let behindParam = ''
  if (!content.includes(mask)) {
    frontLink = content
  } else {
    // 间隔标识
    maskIndex = content.indexOf(mask)
    // 前段的地址
    frontLink = content.slice(0, maskIndex)
    // 后段的参数
    behindParam = content.slice(maskIndex).replace(mask, '')
    if (behindParam) {
      behindParam.split('&').map(item => {
        let items = item.split('=')
        let paramKey = items[0]
        if (paramKey) {
          let paramCode = paramKey
          let paramValue = items[1] || ''
          if (paramValue.startsWith('#{')) {
            const marks = paramValue.match(/#{(.+?)\}/);
            paramCode = marks[1]
            paramValue = ''
          }
          linkInfo.paramList.push({ key: items[0], code: paramCode, value: paramValue })
        }
      })
    }
  }
  linkInfo.linkUrl = frontLink
  // console.log('setLinkInfo', {
  //   frontLink,
  //   maskIndex,
  //   behindParam
  // })
}
/**
 * 新增参数项
 * @param {Number} index 索引
 */
const addParamItem = (index) => {
  linkInfo.paramList.splice(index + 1, 0, { key: '',  code: '', value: '', })
}
/**
 * 删除参数项
 * @param {Number} index 索引
 */
const delParamItem = (index) => {
  linkInfo.paramList.splice(index, 1)
}

/**
 * 获取参数数据
 */
const getParamString = () => {
  const { paramList } = linkInfo
  if (!(paramList && paramList.length)) return ''
  const paramString = paramList.filter(item => item.key).map(item => {
    let value = item.value ? item.value : `#{${item.code || item.key}}`
    return `${item.key}=${value}`
  }).join('&')
  return paramString ? `?${paramString}` : ''
}
/**
 * 获取最终的路径
 */
const getFinalLinkUrl = () => {
  const paramsSting = getParamString()
  const finalLinkUrl = linkInfo.linkUrl + paramsSting
  return finalLinkUrl
}
/**
 * 自动提示查询
 * @param {String} queryString 查询参数
 * @param {Function} callback 回调方法
 */
const paramKeyFilter = (queryString, callback) => {
  const results = queryString
    ? props.fieldOptions.filter((item) => { return item.value.toLowerCase().indexOf(queryString.toLowerCase()) !== -1 })
    : props.fieldOptions
  callback(results)
}

defineExpose({
  handleOpen,
});
</script>

<style lang="scss" scoped>
.params-info-wrapper {
  white-space: nowrap;
  width: 100%;
  padding: 5px;
  border: 1px solid #e5e5e5;
  border-radius: 5px;
  ul {
    list-style: none;
    margin: 0;
    padding: 0;
  }
  .info-row {
    display: flex;
    width: 100%;
    margin-bottom: 5px;
    .info-row-item {
      flex: 1;
      width: 0;
      margin-right: 12px;
    }
    .info-row-item-btn {
      width: 60px;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .info-row-item-label {
      text-align: center;
      font-weight: 600;
    }
    
  }
}
</style>
